/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.service.impl;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.huawei.housekeeper.common.enums.AccountTypeEnum;
import com.huawei.housekeeper.common.enums.ErrorCode;
import com.huawei.housekeeper.commonutils.constants.DeletedFlagEnum;
import com.huawei.housekeeper.commonutils.exception.Assert;
import com.huawei.housekeeper.commonutils.result.ListRes;
import com.huawei.housekeeper.commonutils.utils.CommonUtil;
import com.huawei.housekeeper.commonutils.utils.TokenUtil;
import com.huawei.housekeeper.controller.converter.UserConverter;
import com.huawei.housekeeper.controller.request.CreateUserDto;
import com.huawei.housekeeper.controller.request.GetUserDto;
import com.huawei.housekeeper.controller.request.GetWorkUserInfoDto;
import com.huawei.housekeeper.controller.request.PageQueryUserDto;
import com.huawei.housekeeper.controller.response.GetTenantUserInfoVo;
import com.huawei.housekeeper.controller.response.GetUserInfoVo;
import com.huawei.housekeeper.controller.response.GetUserVo;
import com.huawei.housekeeper.controller.response.GetWorkUserInfoVo;
import com.huawei.housekeeper.dao.entity.User;
import com.huawei.housekeeper.dao.mapper.UserMapper;
import com.huawei.housekeeper.service.UserService;

/**
 * 用户信息服务实现类
 *
 * @author l84165417
 * @since 2022-02-11
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TokenUtil tokenUtil;

    /**
     * 创建用户信息
     *
     * @param createUserDto 用户dto
     * @return userId
     */
    @Override
    public String createUserInfo(CreateUserDto createUserDto) {
        User user = UserConverter.INSTANCE.createUserToUser(createUserDto);
        user.setUserId(CommonUtil.getUUID());
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));

        // 用户名重复校验
        String userName = createUserDto.getUserName();
        User userFromDb = userMapper.getByUserName(userName);
        Assert.isTrue(userFromDb == null, ErrorCode.USERNAME_REPEATED.getCode(),
                ErrorCode.USERNAME_REPEATED.getMessage());

        // 注册账户类型 账户类型默认为“1” 用户
        AccountTypeEnum typeEnum = AccountTypeEnum.ofAccountType(createUserDto.getAccountType())
                .orElseGet(() -> AccountTypeEnum.ACCOUNT_USER);
        createUserDto.setAccountType(typeEnum.getCode());
        if (typeEnum == AccountTypeEnum.ACCOUNT_WORKER) {
            Assert.notBlank(createUserDto.getIdCard(), ErrorCode.IS_EMPTY.getCode(),
                    ErrorCode.IS_EMPTY.getMessage());
        }
        // 删除标记
        user.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        userMapper.insert(user);
        return user.getUserId();
    }

    /**
     * 分页查询用户信息
     *
     * @param pageQueryUserDto 分页请求
     * @return 用户列表
     */

    @Override
    public ListRes<GetUserVo> pageQueryUsers(PageQueryUserDto pageQueryUserDto) {
        Page<User> userPage = new Page<>(pageQueryUserDto.getCurrent(), pageQueryUserDto.getSize());
        // 查询分页结果
        LambdaQueryWrapper<User> selectList = Wrappers.lambdaQuery();
        selectList.eq(User::getUserName, pageQueryUserDto.getUserName());
        IPage<User> users = userMapper.selectPage(userPage, selectList);
        List<GetUserVo> userVos = UserConverter.INSTANCE.toGetUserVo(users.getRecords());
        return new ListRes<>(userVos, (int) users.getTotal());
    }

    /**
     * 查询用户信息
     *
     * @param userDto 用户请求
     * @return UserVo
     */
    @Override
    public ListRes<GetUserVo> getUserInfo(GetUserDto userDto) {
        LambdaQueryWrapper<User> selectList = Wrappers.lambdaQuery();
        Assert.notEmpty(userDto.getUserName(), ErrorCode.IS_EMPTY.getCode(), ErrorCode.IS_EMPTY.getMessage());
        selectList.eq(User::getUserName, userDto.getUserName());
        List<User> users = userMapper.selectList(selectList);
        List<GetUserVo> userVos = UserConverter.INSTANCE.toGetUserVo(users);
        return new ListRes<>(userVos, 0);
    }

    /**
     * 删除用户信息
     *
     * @param userId 用户id
     * @return boolean
     */
    @Override
    public Boolean deleteUserInfoByUserId(String userId) {
        String userIdLogging = tokenUtil.getUidFromHeader();
        // 判断用户是否已登录
        Assert.isFalse(userId.equals(userIdLogging), ErrorCode.DELETE_ERROR.getCode(), ErrorCode.DELETE_ERROR.getMessage());
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(User::getUserId, userId);
        User updateObj = new User();
        // 设置删除标记 "1"
        updateObj.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
        userMapper.update(updateObj, queryWrapper);
        return true;
    }

    /**
     * 查询用户信息详情
     *
     * @return 用户信息
     */
    @Override
    public GetUserInfoVo getUserInfoById() {
        String userId = tokenUtil.getUidFromHeader();
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUserId, userId);
        wrapper.eq(User::getAccountType, AccountTypeEnum.ACCOUNT_USER.getCode());
        return UserConverter.INSTANCE.toGetUserInfoVo(userMapper.selectOne(wrapper));
    }

    /**
     * 租户查询用户信息列表
     *
     * @param pageQueryUserDto 分页请求
     * @return TenantUserInfoVo
     */
    @Override
    public ListRes<GetTenantUserInfoVo> getUserInfoList(PageQueryUserDto pageQueryUserDto) {
        LambdaQueryWrapper<User> select = Wrappers.lambdaQuery();
        select.eq(User::getAccountType, AccountTypeEnum.ACCOUNT_USER.getCode());
        Page<User> page = new Page<>(pageQueryUserDto.getCurrent(), pageQueryUserDto.getSize());
        IPage<User> userPage = userMapper.selectPage(page, select);
        List<User> user = Optional.ofNullable(userPage.getRecords()).orElseGet(() -> {
            return Lists.newArrayList();
        });
        List<GetTenantUserInfoVo> tenantUserInfoVos = UserConverter.INSTANCE.toGetTenantUserInfoVo(user);
        return new ListRes<>(tenantUserInfoVos, 0);
    }

    /**
     * 查询工人信息
     *
     * @param workUserInfoDto 工人请求
     * @return WorkUserInfoVo
     */
    @Override
    public GetWorkUserInfoVo getWorkInfo(GetWorkUserInfoDto workUserInfoDto) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StringUtils.isNotBlank(workUserInfoDto.getUserId()), User::getUserId, workUserInfoDto.getUserId());
        wrapper.eq(User::getAccountType, AccountTypeEnum.ACCOUNT_WORKER.getCode());
        return UserConverter.INSTANCE.toGetWorkUserInfoVo(userMapper.selectOne(wrapper));
    }
}